7장. 통합 강도

출처: 『소프트웨어 설계의 결합 균형』(블라드 코노노프 지음, 장연호 옮김, 제이펍 2026) | 공식: https://www.jpub.kr/

5장의 모듈 결합(6단계)과 6장의 공생성 두 모델을 하나로 통합한 통합 강도 (Integration Strength) 모델을 소개한다. 두 선배 모델이 각각 보지 못하는 사각지대를 보완하여, 침입·기능·모델·계약의 4수준으로 단순화·통합한 실용 척도다.


학습 목표

이 장을 끝내면 다음을 할 수 있다.

  • 통합 강도 4수준(침입·기능·모델·계약)을 일상 비유로 설명한다.
  • 두 모듈의 인터페이스를 보고 어느 통합 강도 수준인지 분류한다.
  • 각 수준에서 공유 지식의 복잡성을 정도(degree)로 평가한다.
  • 5장 모듈 결합·6장 공생성 수준과 통합 강도 수준을 매핑한다.
  • 비동기 통신이 결합 강도를 반드시 낮추지 않는 이유를 설명한다.
  • 데이터베이스 공유, SupportCase, 메시지 버스 예시를 통해 실무에 적용한다.

전체 흐름도

[ 5장 모듈 결합 ]       [ 6장 공생성 ]
        \                    /
         \                  /
          [ 7장 통합 강도 통합 ]
                  |
          두 모델의 사각지대 해소
          (비물리적 연결, 두 모델 동시 미반영)
                  |
    ┌─────────────────────────────────────────┐
    │   강 ▲  1. 침입 결합 (Intrusive)        │  영장 없이 집 안 수색
    │       │     구현 세부 침범              │
    │       ├─────────────────────────────────┤
    │       │  2. 기능 결합 (Functional)      │  같은 레시피 두 식당이 따로 운영
    │       │     공유 비즈니스 로직          │
    │       ├─────────────────────────────────┤
    │       │  3. 모델 결합 (Model)           │  공동 메뉴판을 두 식당이 함께 씀
    │       │     공유 비즈니스 도메인 모델   │
    │       ├─────────────────────────────────┤
    │   약 ▼│  4. 계약 결합 (Contract)        │  표준 주문 양식만 공유
    │       │     통합 전담 모델(계약) 공유   │
    └─────────────────────────────────────────┘
           각 수준은 인터페이스 유형을 반영
           정도(degree)는 공생성 수준으로 평가

0. 사전 필수 용어

  • 통합 강도 (Integration Strength) — 모듈 결합과 공생성을 통합한 새 모델. 인터페이스 유형(수준)과 인터페이스 복잡성(정도) 두 축으로 결합 강도를 평가한다.
  • 인터페이스 유형 — 모듈 간 연결 통로의 종류: 구현 세부(침입)·비즈니스 로직(기능)·도메인 모델(모델)·통합 전담 모델(계약).
  • 인터페이스 복잡성 — 통로를 통해 흐르는 지식의 복잡성. 공생성 수준(이름·유형·의미·알고리즘 등)으로 측정.
  • 정도 (Degree) — 각 통합 강도 수준 안에서 공유 지식이 얼마나 복잡한가. 침입 결합은 정도가 없음(전부 아니면 무).
  • 대칭적 기능 결합 (Symmetric Functional) — 두 모듈이 동일한 기능을 각자 구현하는 경우. DRY 원칙 위반. 비물리적 연결임에도 강한 결합.
  • 계약 (Contract) — 통합을 위해 따로 설계된 전담 모델. 내부 구현 모델과 분리된 '통합 언어'. "모델의 모델"이라 할 수 있다.
  • 구현 모델 — 모듈 내부에서 기능 구현을 위해 쓰는 모델. 외부에 그대로 노출되면 모델 결합.
  • 공유 DB 안티패턴 — 한 서비스의 DB를 다른 서비스가 직접 읽는 패턴. 어떻게 접근하느냐에 따라 침입·모델·계약 결합으로 분류된다.
  • 모듈 깊이 (Module Depth) — 4장 개념. 사각형으로 모듈을 표현할 때 면적(구현 세부)이 하단 변(공개 인터페이스)보다 클수록 '깊은 모듈'. 얕은 계약은 모델 결합과 다를 바 없다.

1. 왜 두 모델을 통합해야 하는가 — 두 선배 모델의 사각지대

1.1 두 모델이 보는 것

5장 모듈 결합(구조적 설계)은 인터페이스 유형(비공개 침범·전역 공유·플래그·데이터)을 잘 포착한다. 6장 공생성은 인터페이스 복잡성(이름·유형·의미·알고리즘·실행·타이밍·값·동일)을 잘 포착한다.

그러나 두 모델을 단순히 하나의 척도로 합치는 것은 불가능하다. 예를 들어:

  • 리플렉션으로 비공개 메서드를 호출하면 → 콘텐츠 결합(가장 강함) + 이름 공생성(가장 약함). 두 모델이 정반대를 가리킨다.
  • 타이밍 공생성(강함)은 데이터 결합(약함)과 완벽하게 공존할 수 있다.

1.2 두 모델이 보지 못하는 것 — 비물리적 연결

일상 비유 — 두 식당이 서로 아무 계약도 맺지 않았는데, 두 식당의 메인 요리 레시피가 사실 완전히 같다. 메뉴가 바뀌면 두 식당 모두 동시에 변경해야 한다. 물리적 문이 연결돼 있지 않아도, 두 식당은 사실상 묶여 있다.

소프트웨어에서도 두 서비스가 물리적으로 직접 연결(API 호출·공유 변수)되지 않아도, 동일한 비즈니스 로직(예: 무료 배송 자격 기준)을 각자 구현하면 — 요구사항이 바뀔 때마다 둘 다 동시에 고쳐야 한다. 이를 모듈 결합·공생성 어느 모델도 포착하지 못한다.


2. 통합 강도 — 4수준 상세

2.1 침입 결합 (Intrusive Coupling) — 영장 없이 집 안 수색

일상 비유 — 경찰이 영장(공개 인터페이스) 없이 집에 들어와 서랍을 뒤집는다. 집주인(상위 모듈)이 서랍 위치를 바꾸면, 경찰의 수색 계획 전체가 깨진다. 더 큰 문제는 집주인이 누가 집에 들어왔는지조차 모른다는 것이다.

소프트웨어: 하위 모듈이 상위 모듈의 구현 세부를 통해 통신한다. 공개 인터페이스를 무시하고 내부에 직접 침범한다. 이 수준을 '침입적'이라 하는 이유는 통합 수단이 상위 모듈 작성자에 의해 고려되지 않았다는 점을 강조하기 위해서다.

침입 결합의 예

// 잘못된 예: 리플렉션으로 비공개 메서드 강제 호출
public void DoSomething() {
    var t = typeof(InvoiceGenerator);
    var privateMethod = t.GetMethod("VerifyInput",
        BindingFlags.NonPublic | BindingFlags.Instance);
    privateMethod.Invoke(invoice, "input");
    // InvoiceGenerator가 VerifyInput을 삭제하면 조용히 폭발
}

문제: InvoiceGenerator 작성자는 이 호출이 존재하는 줄도 모른다. 어떤 내부 변경도 통합을 깨뜨릴 수 있다.

역침입 결합 (역방향 침입)

상용 기성 제품(COTS)의 소스 코드를 직접 수정하여 누락된 알림 기능을 추가하는 경우가 대표적이다. 해킹을 통한 통합의 예로, 제품을 업그레이드하면 소스 코드가 초기화되어 기존 통합이 깨진다.

현대판 침입 결합 — 공유 DB 직접 접근

마이크로서비스 A (DB 소유)
  운영 DB  <── 서비스 B가 직접 SELECT

서비스 B는 서비스 A의 공식 API를 무시하고 DB에 직접 접속한다. 서비스 A가 컬럼 이름을 바꾸면 서비스 B가 조용히 깨진다. 서비스 A는 이 접속의 존재를 모를 수 있다.

참고: ORM 프레임워크가 리플렉션으로 객체 필드에 접근하는 것은 침입 결합이 아니다. 프레임워크를 사용하기로 했을 때 이미 의도적으로 허용한 접근이기 때문이다. 의도가 핵심.

침입 결합이 가장 위험한 이유 3가지

  1. 취약 — 상위 모듈의 어떤 변경도 통합을 깨뜨릴 수 있다.
  2. 암묵적 — 상위 모듈 작성자가 이 통합을 인식하지 못한다.
  3. 캡슐화 파괴 — 상위 모듈의 모든 지식이 하위와 공유되는 것으로 간주해야 한다.

2.2 기능 결합 (Functional Coupling) — 같은 레시피를 두 식당이 각자 운영

일상 비유 — 서울 강남점과 강북점이 같은 본사 레시피대로 요리를 만든다. 레시피가 바뀌면(예: 재료 교체, 조리 순서 변경) 두 지점 모두 동시에 메뉴를 바꿔야 한다. 두 지점이 직접 연결된 문은 없지만, 같은 레시피라는 보이지 않는 끈으로 묶여 있다.

소프트웨어: 두 모듈이 동일하거나 밀접하게 관련된 비즈니스 로직(기능)을 구현한다. 비즈니스 요구사항이 바뀌면 모든 결합된 모듈에 동시에 적용해야 한다.

기능 결합의 특이점

  • 다른 수준과 달리 상위-하위 관계가 없다. 지식이 양방향으로 흐른다.
  • 하나가 바뀌면 다른 쪽도 바뀌어야 한다 → 두 구성요소 모두 상위로 볼 수 있다.
  • 식별 휴리스틱: 비즈니스 요구사항 변경이 여러 모듈의 기능에 영향을 미칠 수 있다면, 해당 모듈들이 기능적으로 결합돼 있을 가능성이 높다.

기능 결합의 3가지 정도(degree)

정도 1 — 순차적 기능 (Sequential/Temporal)

여러 작업을 특정 순서로 호출해야 한다. 예: "로그인 후에만 주문할 수 있다." 타이밍 공생성·실행 공생성이 해당. 순차적 결합(시간적 결합)이라고도 한다.

정도 2 — 트랜잭션 기능 (Transactional)

여러 작업을 하나의 트랜잭션으로 처리해야 한다. 하나가 실패하면 전체 롤백. 예: "DB 업데이트 + 메시지 버스 게시가 함께 성공하거나 함께 실패해야 한다." 값 공생성·동일 공생성이 해당.

트랜잭션 결합의 일반적 증상: 동시성 제어(concurrency control)가 필수적으로 필요해진다.

일상 비유 — 은행 이체는 출금 계좌 감소와 입금 계좌 증가가 동시에 성공해야 한다. 한쪽만 되면 시스템이 망가진다.

정도 3 — 대칭적 기능 (Symmetric / Duplicated)

두 모듈이 동일한 기능을 각자 구현한다. DRY 위반. 요구사항이 바뀌면 둘 다 동시에 고쳐야 하며, 하나라도 빠뜨리면 시스템이 일관성을 잃는다.

대칭적 기능 결합 성립 조건: 1. 두 모듈이 동일한 기능을 구현한다. 알고리즘 구현 방식은 무관하다. 2. 공유 동작에 대한 요구사항이 변경되면 기능적으로 결합된 모든 모듈에서 동시에 변경을 구현해야 한다.

// 잘못된 예: 동일 로직이 두 서비스에 복제됨
// Retail 서비스
bool IsQualifiedForFreeShipping(Order order) {
    return activePromotions.ApplyFor(order) ||
           order.TotalCost > Currency.USD(1000);  // 기준: $1000
}

// Fulfillment 서비스
bool IsQualifiedForFreeShipping(Order order) {
    return activePromotions.ApplyFor(order) ||
           order.TotalCost > Currency.USD(1000);  // 동일한 $1000 기준
}
// 기준이 $800으로 바뀌면? → 둘 다 고쳐야 하고, 하나 빠뜨리면 버그

왜 대칭적 기능이 두 번째로 강한 결합인가? 1. 기능의 모든 변경이 두 모듈에 동시에 반영되어야 한다. 2. 물리적 연결이 없으므로 매우 암묵적이다 — 자동으로 발견하기 어렵다.

기능 결합의 영향

모듈이 구현하는 기능의 지식을 공유하면 인터페이스가 광범위하고 복잡해진다. 모듈 간 관계가 암묵적으로 돼 영향 받는 모듈에서 변경을 빠뜨리기 쉽다.


2.3 모델 결합 (Model Coupling) — 공동 메뉴판을 두 식당이 함께 씀

일상 비유 — 강남점과 강북점이 공동 메뉴판(도메인 모델)을 함께 쓴다. 메뉴판 자체는 공유하지만, 주방 운영(내부 로직)은 각자 따로 한다. 메뉴판에서 항목이 추가·삭제되면, 두 지점 모두 메뉴판을 참조하는 모든 직원이 영향받는다.

소프트웨어: 상위 모듈이 내부 비즈니스 도메인 모델을 공개 인터페이스의 일부로 노출한다. 하위 모듈은 이 모델에 의존한다.

"모든 모델은 틀렸지만 일부 모델은 유용하다." — 조지 박스(George E. P. Box)

모델은 실제 세계를 완전히 반영하는 것이 아니라, 특정 문제를 해결하기에 충분한 정보를 제공하는 것이 목적이다.

모델 결합의 예 — WolfDesk SupportCase

// 잘못된 예: Distribution 모듈이 내부 도메인 모델을 그대로 노출
namespace Distribution {
    public class Customer {
        public Guid Id { get; private set; }
        public string Name { get; private set; }
        public string Email { get; private set; }
        public string Phone { get; private set; }
        // ... 수십 개 필드 (Distribution 내부 구현 세부)
    }

    public Customer GetCustomer(Guid id) { ... }  // 내부 모델을 그대로 반환
}

// Accounting이 이 Customer 모델에 의존
namespace Accounting {
    void Process(Guid customerId) {
        var c = distribution.GetCustomer(customerId);
        // Distribution이 Phone 필드를 삭제하거나 타입을 바꾸면 → Accounting도 영향
    }
}

같은 비즈니스 개체(SupportCase)라도 목적에 따라 모델이 달라야 한다:

// 운영 모델: 지원 사례의 운영 수명주기 관리에 최적화
namespace WolfDesk.SupportCases.Management {
    public class SupportCase {
        public CaseId Id { get; private set; }
        public string Title { get; private set; }
        public AgentId Assignee { get; private set; }
        public CaseStatus Status { get; private set; }
        public List<Message> Messages { get; private set; }
        // ... 운영 트랜잭션 중심 필드
    }
}

// 분석 모델: BI 분석에 최적화
namespace WolfDesk.SupportCases.Analysis {
    public class SupportCase {
        public CaseId Id { get; private set; }
        public int ReopenedCount { get; private set; }
        public int ReassignedCount { get; private set; }
        public TimeSpan LongestResponseTimeByAgent { get; private set; }
        public TimeSpan AverageResponseTimeByAgent { get; private set; }
        // ... 분석 중심 필드
    }
}

두 모델을 하나로 합치면 "모든 분야에 능통하지만, 어느 분야에도 정통하지 못한" 비대하고 최적화되지 않은 모델이 된다.

모델 결합이 기능 결합보다 나은 이유

  1. 데이터 구조 공유 (동작은 공유 안 함) → 비즈니스 로직보다 훨씬 안정적
  2. 인터페이스가 더 명확 → 문서화 가능, 중단 변경 식별 가능
  3. 의도적 접근 → 상위 모듈 작성자가 공유 사실을 알고 관리할 수 있다

모델 결합의 위험

하위 모듈이 공유 모델의 일부만 쓰면 상위 모듈은 불필요한 정보를 함께 공유하게 된다(스탬프 결합과 유사). 모델이 시스템 전체에 퍼지면 많은 구성요소가 최적화되지 않은 모델에 의존하게 된다.


2.4 계약 결합 (Contract Coupling) — 표준 주문 양식만 공유

일상 비유 — 강남점·강북점이 표준 주문 양식(계약)만 공유한다. 양식에는 "메뉴명·수량·테이블번호"만 있다. 각 지점의 내부 운영(재료 구매·조리 방식·직원 배치)은 완전히 분리된다. 강남점이 조리 방식을 바꿔도, 양식 형식이 그대로면 강북점은 영향받지 않는다.

소프트웨어: 상위 모듈이 통합을 위해 별도로 설계한 계약(통합 전담 모델)을 통해 하위 모듈과 통신한다. 내부 구현 모델과 계약은 분리돼 있다. 계약은 "협업 조건을 설명하는 협약"으로, 어떤 의미에서 모델의 모델이다.

계약 결합의 예 — WolfDesk 지원 사례 API

// 내부 운영 모델 (내부에서만 사용)
namespace WolfDesk.SupportCases.Management {
    public class SupportCase {
        public CaseId Id { get; private set; }        // 도메인 전용 타입
        public AgentId Assignee { get; private set; } // 도메인 전용 타입
        public CaseStatus Status { get; private set; }
        // ... 도메인 복잡한 내부 구조
    }
}

// 통합 전담 계약 (외부 노출용)
namespace WolfDesk.SupportCases.Application.API {
    public class SupportCaseDetails {
        public string Id { get; private set; }              // string으로 변환 (플랫폼 호환)
        public string AssignedAgentId { get; private set; } // string으로 단순화
        public string AssignedAgentName { get; private set; }
        public string Status { get; private set; }
        // ... 소비자에게 필요한 최소 정보만
    }

    interface SupportCasesAPI {
        // 명령(Command)
        ExecutionResult Execute(EscalateCase cmd);
        ExecutionResult Execute(ResolveCase cmd);
        ExecutionResult Execute(PutCaseOnHold cmd);
        // 쿼리(Query)
        IEnumerable<SupportCaseDetails> CasesByAgent(string agentId, string status);
        IEnumerable<SupportCaseDetails> CasesByCustomer(string customerId);
        IEnumerable<SupportCaseDetails> EscalatedCases();
    }
}

내부 SupportCase가 어떻게 바뀌든, SupportCaseDetailsSupportCasesAPI만 안정적이면 하위 모듈은 영향받지 않는다.

계약 결합의 이점 3가지

  1. 계약이 구현 모델보다 안정적 — 내부 모델은 자유롭게 진화해도 계약이 유지되면 변경이 하위로 전파되지 않는다.
  2. 공유 지식 최소화 — 계약만 노출, 구현 모델은 경계 뒤에 캡슐화
  3. 버전 관리 가능 — 상위 모듈이 동시에 여러 계약 버전을 노출할 수 있다(소비자가 점진적 마이그레이션)

계약 결합의 정도 경계 — 함정 주의

계약처럼 보여도 실제로는 모델 결합일 수 있다.

// 잘못된 예: MessageDTO가 Message와 완전히 동일한 구조
public class Message {         // 내부 모델
    public Guid Id { get; private set; }
    public string Body { get; private set; }
    public DateTime SentOn { get; private set; }
    public Guid SentBy { get; private set; }
}

public class MessageDTO {      // "계약"이라고 만들었지만...
    public Guid Id { get; private set; }
    public string Body { get; private set; }
    public DateTime SentOn { get; private set; }   // Message와 완전히 동일
    public Guid SentBy { get; private set; }
}

MessageDTO는 어떤 지식도 캡슐화하지 않는다. Message에 대한 변경이 MessageDTO에 미러링될 가능성이 높다 → 사실상 모델 결합. 계약이 가치 있으려면 내부 모델의 세부를 실제로 추상화해야 한다.

4장의 모듈 깊이 개념 적용: MessageDTO는 사각형의 면적이 하단 밑변과 동일한 '얕은 모듈'이다. 어떤 지식도 숨기지 않으므로 불필요한 복잡성만 추가한다.

계약 결합과 디자인 패턴의 관계

GoF 디자인 패턴이 계약 결합을 다양한 형태로 구현한다: - 파사드 (Facade) — 하위 시스템 집합에 통합된 단일 인터페이스 제공 - 브리지 (Bridge) — 추상화와 구현을 분리해 독립적 진화 - 어댑터 (Adapter) — 호환되지 않는 인터페이스를 연결

단일 객체에서도: 공개 메서드는 하나 이상의 비공개 메서드에 처리를 전달하는 형태로 계약 역할을 한다.

표준 프로토콜도 계약의 한 형태: SMTP·IMAP·POP3는 이메일 서비스의 통합 계약이다.

주의: 계약 결합을 절대적인 최종 목표로 취급해서는 안 된다. 코드를 복잡하게 만들기만 하는 얕은 DTO는 계약 결합이 아니라 오히려 해롭다.


3. 통합 강도와 비동기 실행

일상 오해 — "메시지 큐를 쓰면 무조건 느슨하게 결합된다."

정답 — 통신 방식(동기/비동기)은 통합 강도에 영향을 주지 않는다. 중요한 것은 경계를 가로질러 공유되는 지식의 유형이다.

메시지 큐를 통해 통신하는 서비스라도:

상황 통합 강도
통합 전담 계약 모델로 메시지 전달 계약 결합
비즈니스 도메인 모델 형식으로 데이터 푸시 모델 결합
일정 지연 후에만 처리 (타이밍 의존) 기능 결합 (타이밍 공생성 정도)
생산자·소비자 작업이 함께 성공/실패해야 함 기능 결합 (값 공생성 정도)
메시지 버스 자체가 내부 구현 세부 침입 결합

4. 실행 예제 종합 — 공유 DB, 네 가지 시나리오

동일한 공유 DB 설계라도 어떻게 접근하느냐에 따라 통합 강도가 달라진다.

시나리오 통합 강도 설명
DB가 서비스 A 내부 구현, 서비스 B가 직접 읽음 침입 결합 공개 API 우회, 암묵적
두 서비스가 같은 테이블 읽고 쓰며 동일 비즈니스 규칙 따름 기능 결합 데이터 일관성 위해 같은 로직 공유, 동일 공생성
서비스 A DB를 공개 인터페이스로 허용, 서비스 B가 내부 모델 읽음 모델 결합 의도적이나 내부 모델 노출
통합 전담 테이블(제한된 스키마)을 DB에 두고 서비스 B가 읽음 계약 결합 통합 모델이 구현 모델과 분리

5. 분산 시스템 예제 — 통합 강도 복합 분석

서비스 A가 데이터베이스와 메시지 버스를 통해 여러 서비스와 연결되는 복합 시나리오:

  1. 서비스 A ↔ 운영 DB, 메시지 버스 — DB 업데이트와 이벤트 게시가 함께 성공·실패해야 한다 → 기능 결합 (값 공생성 정도, 트랜잭션)
  2. 서비스 A ↔ 서비스 C — 서비스 C는 서비스 A가 게시한 비즈니스 도메인 모델을 사용한다 → 모델 결합
  3. 서비스 C ↔ 서비스 D — 서비스 D는 서비스 C가 처리할 충분한 시간을 확보하기 위해 30초 지연 후 실행된다 → 기능 결합 (타이밍 공생성 정도, 순차적)

6. 통합 강도와 선배 모델 매핑

통합 강도 수준 유사한 구조적 설계 (5장) 유사한 공생성 (6장)
침입 결합 콘텐츠 결합 (동의어)
기능 결합 (순차·트랜잭션) 공통·외부·제어 결합 실행·타이밍·값·동일 공생성
기능 결합 (대칭적) — (사각지대) — (사각지대)
모델 결합 스탬프 결합 정적 공생성 (이름·유형·의미·알고리즘·의미적)
계약 결합 데이터 결합 정적 공생성 (단, 실제 캡슐화 수반)

핵심 개념 정리

개념 한 줄 설명
통합 강도 모듈 결합 + 공생성 통합 모델. 인터페이스 유형(수준)과 복잡성(정도) 두 축
침입 결합 구현 세부 침범. 가장 강함. 영장 없는 집 수색
기능 결합 공유 비즈니스 로직. 상위-하위 없음, 양방향
대칭적 기능 결합 동일 기능 복제. DRY 위반. 비물리적 연결이지만 강한 결합
모델 결합 내부 도메인 모델 공유. 의도적이나 구현 세부 누출
계약 결합 통합 전담 모델 공유. 가장 약함. 내부 모델과 분리
정도(degree) 각 수준 내 지식 복잡성. 공생성으로 평가. 침입 결합은 정도 없음
비동기 ≠ 약한 결합 통신 방식이 아니라 공유 지식 유형이 통합 강도를 결정
역침입 결합 COTS 제품 소스 수정 같은 역방향 침입. 업그레이드 시 파괴됨
얕은 계약 DTO가 내부 모델을 그대로 복제할 때. 계약 가치 없음, 사실상 모델 결합

실무 체크리스트

  • [ ] 다른 서비스의 DB에 공식 API 없이 직접 접속하는 곳이 있는가? (침입 결합)
  • [ ] 동일한 비즈니스 규칙이 두 모듈에 복제돼 있는가? (대칭적 기능 결합)
  • [ ] 요구사항이 바뀔 때 반드시 함께 변경해야 하는 모듈 쌍이 있는가? (기능 결합 일반)
  • [ ] 내부 도메인 모델을 공개 API에 그대로 노출하고 있는가? (모델 결합)
  • [ ] 통합 전담 DTO/계약이 내부 모델의 세부를 실제로 추상화하는가, 아니면 그냥 복사본인가?
  • [ ] "메시지 큐/비동기로 바꾸면 결합이 줄어든다"는 가정을 하고 있는가? (통신 방식 ≠ 통합 강도)
  • [ ] 두 모듈의 통합 강도를 수준(유형) + 정도(복잡성)로 동시에 평가하고 있는가?
  • [ ] GoF 파사드·브리지·어댑터 패턴이 계약 결합을 구현하는 방식인지 인식하고 있는가?
  • [ ] 비즈니스 요구사항 변경이 여러 모듈을 동시에 변경하게 만든다면 기능 결합 여부를 검토했는가?
  • [ ] 상용 기성 제품(COTS) 소스를 직접 수정하거나 DB를 우회 접근하지는 않는가? (침입/역침입 결합)

연습문제 (문제만 — 정답은 부록 D)

  1. 개념. 기능 결합에서 "상위-하위 관계가 없다"고 하는 이유는 무엇인가? 이것이 침입·모델·계약 결합과 어떻게 다른가?

  2. 분류. 주문 서비스와 배송 서비스가 같은 PostgreSQL 테이블에서 데이터를 읽고 쓴다. 두 서비스 모두 "주문 잔액은 0 이상"이라는 비즈니스 규칙을 각자 검증 코드로 구현하고 있다. 이 상황에서 두 서비스 사이의 통합 강도 수준과 정도를 각각 진단하라.

  3. 판단. 다음 주장을 평가하라: "메시지 큐를 도입하면 서비스 간 결합이 반드시 약해진다." 반례를 두 가지 들어 이 주장이 틀렸음을 보여라.

  4. 리팩토링. 다음 코드에서 통합 강도 수준을 진단하고 계약 결합으로 개선하는 예를 보여라. csharp // Distribution 서비스가 내부 모델을 그대로 노출 public class Customer { public Guid Id { get; set; } public string InternalCode { get; set; } // 내부 코드 public string Name { get; set; } public List<Order> OrderHistory { get; set; } // 무거운 내부 객체 } public Customer GetCustomer(Guid id) { ... }

  5. 적용. 음식 배달 앱(주문·결제·배달 세 서비스)을 설계한다고 가정한다. (a) 주문과 결제가 트랜잭션으로 묶여야 하는 경우, (b) 배달 서비스가 주문 정보를 읽는 경우 — 각각의 통합 강도 수준과 적절한 정도를 선택하고 이유를 설명하라.


최신 동향 (2026-05 기준)

최신 동향 (검증 2026-05-31) — 통합 강도의 원리는 그대로 유효하며, 마이크로서비스·이벤트 기반 아키텍처의 확산으로 실무 적용 중요성이 높아졌다.

  • 이벤트 기반 아키텍처에서의 통합 강도 — AsyncAPI·CloudEvents 표준은 이벤트 스키마를 명시적 계약으로 다루어 계약 결합을 구현하는 실용 도구로 자리잡았다. 반면 이벤트 페이로드에 내부 도메인 모델을 그대로 담는 패턴은 모델 결합의 분산판으로 경계 대상이다.
  • 마이크로서비스 설계 가이드 — Sam Newman의 "Building Microservices(2nd ed.)" 등 현대 마이크로서비스 설계서들이 "공유 DB 안티패턴"과 "계약 우선(Contract-First) 설계"를 핵심 원칙으로 명시한다. 통합 강도의 4수준이 이 원칙들을 체계적으로 설명하는 이론적 기반으로 사용 가능하다.
  • 도메인 주도 설계(DDD)와의 정합성 — DDD의 경계 컨텍스트(Bounded Context)와 컨텍스트 매핑 패턴은 모델 결합과 계약 결합의 실천적 구현 방법론이다. 특히 Anti-Corruption Layer(ACL) 패턴은 계약 결합의 대표적 구현체로 이해할 수 있다.

부록 A. 용어 사전

한글 용어 원문 영문명 의미
통합 강도 Integration Strength 모듈 결합·공생성을 통합한 결합 강도 평가 모델
침입 결합 Intrusive Coupling 공개 인터페이스 무시, 구현 세부 침범. 최강
역침입 결합 Reverse Intrusive Coupling COTS 소스 수정 등 역방향 침입. 업그레이드 시 파괴
기능 결합 Functional Coupling 공유 비즈니스 로직·기능. 양방향
대칭적 기능 결합 Symmetric Functional Coupling 동일 기능 복제. DRY 위반. 비물리적 연결
순차적 기능 결합 Sequential Functional Coupling 특정 순서 의존. 타이밍·실행 공생성 정도
트랜잭션 기능 결합 Transactional Functional Coupling 작업 단위 의존. 값·동일 공생성 정도
모델 결합 Model Coupling 내부 도메인 모델 공유
계약 결합 Contract Coupling 통합 전담 모델(계약) 공유. 최약
계약 Contract 통합을 위해 설계된 전담 모델. 내부 모델과 분리. 모델의 모델
구현 모델 Implementation Model 모듈 내부 기능 구현용 모델
정도(degree) Degree 각 수준 내 공유 지식의 복잡성. 공생성으로 측정
공유 DB 안티패턴 Shared Database Anti-pattern 여러 서비스가 한 DB를 직접 공유하는 설계
의미 결합 Semantic Coupling 모델·계약 결합을 통칭하는 기존 용어 (이 책에서 미사용)
모듈 깊이 Module Depth 4장 개념. 면적(구현)/밑변(인터페이스) 비율. 얕은 계약은 가치 없음

부록 B. 핵심 비교표

통합 강도 4수준 한눈에

수준 일상 비유 공유 지식 유형 방향성 변경 전파 위험 정도(공생성)
침입 결합 영장 없는 집 수색 구현 세부 전부 단방향 최고 없음 (전부 아니면 무)
기능 결합 두 지점 같은 레시피 비즈니스 로직·기능 양방향 매우 높음 동적 공생성 4단계 + 대칭적
모델 결합 공동 메뉴판 도메인 데이터 모델 단방향 중간 정적 공생성 5단계
계약 결합 표준 주문 양식 통합 전담 모델만 단방향 낮음 정적 공생성 5단계

5장(모듈 결합) · 6장(공생성) · 7장(통합 강도) 3중 매핑

통합 강도 (7장) 모듈 결합 (5장) 공생성 (6장) 핵심 차이
침입 결합 콘텐츠 결합 동의어. 현대판(DB 직접 접근) 포함
기능 결합 (대칭적) — (사각지대) — (사각지대) 비물리적 연결 포착. 두 선배 모델의 맹점
기능 결합 (순차·트랜잭션) 공통·외부·제어 결합 실행·타이밍·값·동일 공생성 함께 보는 것이 더 정확
모델 결합 스탬프 결합 정적 공생성 데이터 구조 공유 (동작 제외)
계약 결합 데이터 결합 정적 공생성 (낮은 정도) 통합 전담 추상화 계층 추가

부록 C. 추천 참고 자료

Tier 1 공식·표준

자료 링크
책 공식 (제이펍) jpub.kr
원서 — Manning Balancing Coupling in Software Design
마이크로서비스 패턴 (Chris Richardson) microservices.io/patterns
Database per Service 패턴 microservices.io
AsyncAPI 표준 (이벤트 계약) asyncapi.com
OpenAPI 표준 (REST 계약) openapis.org

책 다른 장 안내

설명
5장 모듈 결합 6수준 (통합 강도의 한 토대)
6장 공생성 (통합 강도의 다른 토대)
8장 거리 — 통합 강도의 추가 차원
9장 변동성 — 통합 강도의 추가 차원
10장 결합 균형 — 언제 강한 결합이 받아들일 만한가

부록 D. 연습문제 풀이

  1. (기능 결합 양방향성) 기능 결합에서는 두 모듈이 동일하거나 밀접한 비즈니스 로직을 공유한다. 어느 한쪽이 바뀌면 다른 쪽도 영향받는다 — 어느 쪽이 '제공자'이고 어느 쪽이 '소비자'라 특정할 수 없다. 이것이 상위-하위가 없다는 뜻이다. 반면 침입·모델·계약 결합은 모두 명확한 상위(제공자)와 하위(소비자)가 있고 지식은 상위→하위 방향으로만 흐른다.

  2. (대칭적 기능 결합 + 동일 공생성) 두 서비스가 같은 테이블에서 읽고 쓰며 같은 비즈니스 규칙을 각자 구현하는 것은 두 가지 결합이 겹친다. ① 같은 테이블 데이터 셋을 공유하며 강한 일관성이 필요 → 기능 결합 (동일 공생성 정도). ② "잔액 0 이상" 규칙이 복제 → 대칭적 기능 결합. 규칙 기준이 바뀌면 두 서비스 모두 동시에 수정해야 하고, 하나라도 빠뜨리면 두 서비스가 모순된 결정을 내린다.

  3. (비동기 ≠ 약한 결합 반례 2가지) ① 생산자가 내부 도메인 모델 형식으로 이벤트를 발행하고 소비자가 그 구조를 알아야 한다면 → 비동기임에도 모델 결합. ② 소비자가 30초 지연 후에만 메시지를 처리해야 하는 타이밍 의존이 있다면 → 기능 결합 (타이밍 공생성 정도). 통신 방식(동기/비동기)은 공유 지식 유형을 바꾸지 않는다.

  4. (계약 결합으로 개선) ```csharp // 통합 전담 계약 모델 도입 namespace Distribution.Integration.Contracts { public class CustomerSummary { // 소비자에게 필요한 최소 정보만, 내부 코드·주문 이력 제외 public string Id { get; private set; } // Guid → string 단순화 public string Name { get; private set; } public static CustomerSummary From(Customer c) => new CustomerSummary { Id = c.Id.ToString(), Name = c.Name }; } }

// Distribution이 계약 모델만 노출 public CustomerSummary GetCustomer(Guid id) { var c = _repo.Find(id); return CustomerSummary.From(c); // 내부 Customer는 경계 뒤에 숨겨짐 } `` 이제 내부Customer가 어떻게 진화해도CustomerSummary` 계약만 안정적이면 소비자는 영향받지 않는다.

  1. (배달 앱 통합 강도 선택) (a) 주문과 결제: 기능 결합 (트랜잭션 정도, 값 공생성). 이체와 마찬가지로 "주문 생성"과 "결제 승인"은 함께 성공·실패해야 하며, 이를 위해 두 서비스가 같은 데이터 변경에 대한 지식을 공유한다. (b) 배달 서비스가 주문 정보 읽기: 계약 결합 (이름·유형 공생성 정도)가 이상적. 주문 서비스가 배달에 필요한 최소 정보(주소·상품명·수량)만 담은 통합 전담 DTO를 노출한다. 주문 서비스의 내부 모델(결제 이력·프로모션 코드 등)은 배달 서비스가 알 필요가 없다.
난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플